package com.pactera.madp.cp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.common.core.constant.CommonConstants;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.common.security.util.SecurityUtils;
import com.pactera.madp.common.sequence.sequence.Sequence;
import com.pactera.madp.cp.api.dto.beta.WorkOriginalDTO;
import com.pactera.madp.cp.api.dto.beta.WorkNewsQueryDTO;
import com.pactera.madp.cp.api.em.beta.NewsChannelEnum;
import com.pactera.madp.cp.api.em.beta.NewsStateEnum;
import com.pactera.madp.cp.api.em.beta.NewsTypeEnum;
import com.pactera.madp.cp.api.entity.CpApprovalEntity;
import com.pactera.madp.cp.api.entity.beta.WorkChoreographyEntity;
import com.pactera.madp.cp.api.entity.beta.WorkOriginalEntity;
import com.pactera.madp.cp.api.vo.beta.WorkOriginalMidVO;
import com.pactera.madp.cp.api.vo.beta.WorkOriginalVO;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pactera.madp.cp.mapper.beta.WorkChoreographyMapper;
import com.pactera.madp.cp.mapper.beta.WorkOriginalMapper;
import com.pactera.madp.cp.service.CpApprovalService;
import com.pactera.madp.cp.service.WorkNewsGroupService;
import com.pactera.madp.cp.service.WorkOriginalService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @title 原创资讯业务表-业务接口实现
 * @date 2022-06-11
 * @author Deming.Chang
 */
@Service
@RequiredArgsConstructor
public class WorkOriginalServiceImpl extends ServiceImpl<WorkOriginalMapper, WorkOriginalEntity> implements WorkOriginalService {

    /**
     * 序列-业务服务
     */
    private final Sequence sequence;
    /**
     * 审批-业务服务
     */
    private final CpApprovalService cpApprovalService;
    /**
     * 精编系列-业务服务
     */
    private final WorkChoreographyMapper workChoreographyMapper;
    /**
     * 资讯分组-业务服务
     */
    private final WorkNewsGroupService newsGroupService;


    @Override
    public Page<WorkOriginalVO> getWorkOriginalList(Page page, WorkOriginalDTO dto) {
        if(dto.getSign()==1||dto.getSign()==2){
            baseMapper.getChoreographyListPage(page,
                    dto.getGroupId(),
                    dto.getNewsTitle(),
                    dto.getState(),
                    dto.getSign());
        }else{
            baseMapper.getOriginalListPage(page,
                    dto.getGroupId(),
                    dto.getNewsTitle(),
                    dto.getState());
        }
        List<WorkOriginalVO> workOriginalVOList = new ArrayList<>();
        List<WorkOriginalVO> list = page.getRecords();
        for (WorkOriginalVO e : list) {
            WorkOriginalVO WorkOriginalVO = new WorkOriginalVO();
            BeanUtil.copyProperties(e, WorkOriginalVO);
            List<String> tags = JSONUtil.toList(JSONUtil.parseArray(e.getNewsTags()), String.class);
            WorkOriginalVO.setNewsTags(tags);
            workOriginalVOList.add(WorkOriginalVO);
        }
        page.setRecords(workOriginalVOList);
        return page;
    }

    @Override
    public Boolean putOnWorkOriginal(String newsKey) {
        WorkOriginalEntity workOriginalEntity = baseMapper.selectOne(Wrappers.<WorkOriginalEntity>lambdaQuery()
                .eq(WorkOriginalEntity::getNewsKey, newsKey));
        WorkChoreographyEntity workChoreographyEntity = workChoreographyMapper.selectOne(Wrappers.<WorkChoreographyEntity>lambdaQuery()
                .eq(WorkChoreographyEntity::getNewsKey, newsKey));

        if (ObjectUtil.isNotEmpty(workOriginalEntity)){
            if(workOriginalEntity.getState()!=1 && workOriginalEntity.getState()!=4){
                throw new CheckedException("该资讯已上架或者待审批中，不允许上架");
            }else{

                if(workOriginalEntity.getChannel()== NewsChannelEnum.SELF.getChannel()){
                    workOriginalEntity.setNewsKey(newsKey)
                            .setState(NewsStateEnum.UN_APPROVE.getState())
                            .setNewsTime(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
                    baseMapper.updateById(workOriginalEntity);
                }else {
                    workOriginalEntity.setNewsKey(newsKey)
                            .setState(NewsStateEnum.UN_APPROVE.getState());
                    baseMapper.updateById(workOriginalEntity);
                }
            }
        }else if(ObjectUtil.isNotEmpty(workChoreographyEntity)){
            if(workChoreographyEntity.getState()!=NewsStateEnum.UN_PUBLISH.getState() && workChoreographyEntity.getState()!=NewsStateEnum.REJECTED.getState()){
                throw new CheckedException("该资讯已上架或者待审批中，不允许上架");
            }else{
                workChoreographyEntity.setNewsKey(newsKey).setState(NewsStateEnum.UN_APPROVE.getState());
                workChoreographyMapper.updateById(workChoreographyEntity);
            }
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean downWorkOriginal(String newsKey) {
        WorkOriginalEntity workOriginalEntity = baseMapper.selectOne(Wrappers.<WorkOriginalEntity>lambdaQuery()
                .eq(WorkOriginalEntity::getNewsKey, newsKey));
        WorkChoreographyEntity workChoreographyEntity = workChoreographyMapper.selectOne(Wrappers.<WorkChoreographyEntity>lambdaQuery()
                .eq(WorkChoreographyEntity::getNewsKey, newsKey));

        if (ObjectUtil.isNotEmpty(workOriginalEntity)){
            if(workOriginalEntity.getState()!=NewsStateEnum.PUBLISHED.getState()){
                throw new CheckedException("该资讯未发布，不允许下架");
            }else{
                workOriginalEntity.setNewsKey(newsKey).setState(1);
                baseMapper.updateById(workOriginalEntity);
            }
        }else if(ObjectUtil.isNotEmpty(workChoreographyEntity)){
            if(workChoreographyEntity.getState()!=NewsStateEnum.PUBLISHED.getState()){
                throw new CheckedException("该资讯未发布，不允许下架");
            }else{
                workChoreographyEntity.setNewsKey(newsKey).setState(NewsStateEnum.UN_PUBLISH.getState());
                workChoreographyMapper.updateById(workChoreographyEntity);
            }
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean revokeWorkOriginal(String newsKey) {
        WorkOriginalEntity workOriginalEntity = baseMapper.selectOne(Wrappers.<WorkOriginalEntity>lambdaQuery()
                .eq(WorkOriginalEntity::getNewsKey, newsKey));
        WorkChoreographyEntity workChoreographyEntity = workChoreographyMapper.selectOne(Wrappers.<WorkChoreographyEntity>lambdaQuery()
                .eq(WorkChoreographyEntity::getNewsKey, newsKey));
        if (ObjectUtil.isNotEmpty(workOriginalEntity)){
            if(workOriginalEntity.getState()!=NewsStateEnum.UN_APPROVE.getState()){
                throw new CheckedException("该资讯未待审批，禁止撤销");
            }else{
                workOriginalEntity.setNewsKey(newsKey).setState(1);
                baseMapper.updateById(workOriginalEntity);
            }
        }else if(ObjectUtil.isNotEmpty(workChoreographyEntity)){
            if(workChoreographyEntity.getState()!=NewsStateEnum.UN_APPROVE.getState()){
                throw new CheckedException("该资讯未待审批，禁止撤销");
            }else{
                workChoreographyEntity.setNewsKey(newsKey).setState(1);
                workChoreographyMapper.updateById(workChoreographyEntity);
            }
        }

        return Boolean.TRUE;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean ApprovalWorkOriginal(WorkOriginalEntity entity,String newsKey, String opinion, Integer state) {
        LocalDateTime onTime = state == 2 ? LocalDateTime.now() : null;
        Integer updateState = NewsStateEnum.REJECTED.getState();
        if (state != null && state == NewsStateEnum.PUBLISHED.getState()) {
            updateState = NewsStateEnum.PUBLISHED.getState();
        }
        entity.setState(updateState).setUpdateTime(onTime);
        entity.setNewsKey(newsKey);
        WorkChoreographyEntity workChoreographyEntity = new WorkChoreographyEntity();
        workChoreographyEntity.setNewsKey(newsKey);
        workChoreographyEntity.setState(updateState);
        int flag = baseMapper.updateById(entity);
        int flag2 = workChoreographyMapper.updateById(workChoreographyEntity);
        if(flag > 0 ||flag2 > 0){
            Integer createUserId = SecurityUtils.getUser().getId();
            String createUserName = SecurityUtils.getUser().getUsername();
            Long approvalId = sequence.nextValue();
            CpApprovalEntity approvalEntity = new CpApprovalEntity();
            approvalEntity.setId(approvalId);
            approvalEntity.setItemId(newsKey);
            approvalEntity.setItemType(7);
            approvalEntity.setApprovalPreState(NewsStateEnum.UN_APPROVE.getState());
            approvalEntity.setApprovalPostState(updateState);
            approvalEntity.setApprovalType(state);
            approvalEntity.setApprovalUserId(createUserId);
            approvalEntity.setApprovalUserName(createUserName);
            cpApprovalService.save(approvalEntity);
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean saveInfo(WorkOriginalDTO dto) {
        WorkOriginalEntity workOriginalEntity = new WorkOriginalEntity();
        workOriginalEntity.setNewsTitle(dto.getNewsTitle())
                .setNewsAuthor(dto.getNewsAuthor())
                .setNewsAccount(dto.getNewsAccount())
                .setType(dto.getGroupId())
                .setNewsImg(dto.getNewsImg())
                .setAudioUrl(dto.getAudioUrl())
                .setNewsContent(dto.getNewsContent())
                .setState(NewsStateEnum.UN_PUBLISH.getState())
                .setNewsKey(IdUtil.objectId())
                .setChannel(NewsChannelEnum.SELF.getChannel())
        .setCreateUserId(SecurityUtils.getUser().getId())
        .setCreateUserName(SecurityUtils.getUser().getUsername());
        baseMapper.insert(workOriginalEntity);
        return Boolean.TRUE;
    }

    @Override
    public Boolean updateInfo(WorkOriginalDTO dto) {
        WorkOriginalEntity workOriginalEntity = new WorkOriginalEntity();
        workOriginalEntity.setNewsTitle(dto.getNewsTitle())
                .setNewsAuthor(dto.getNewsAuthor())
                .setNewsAccount(dto.getNewsAccount())
                .setType(dto.getGroupId())
                .setNewsImg(dto.getNewsImg())
                .setAudioUrl(dto.getAudioUrl())
                .setNewsContent(dto.getNewsContent())
                .setState(NewsStateEnum.UN_PUBLISH.getState())
                .setNewsKey(dto.getNewsKey());
        int row = baseMapper.updateById(workOriginalEntity);
        if(row<=0){
            throw new CheckedException("更新失败");
        }
        return Boolean.TRUE;
    }

    @Override
    public Boolean deleteInfo(String newsKey) {
        if(!"".equals(newsKey)&& newsKey != null){
            baseMapper.deleteById(newsKey);
        }else {
            throw new CheckedException("未找到资讯唯一标识，删除失败");
        }
        return Boolean.TRUE;
    }

    @Override
    public List<WorkOriginalMidVO> getLatestTwoBeta() {
        return baseMapper.selectLatestTwoBeta();
    }

    @Override
    public List<WorkOriginalMidVO> getLatestTwoBank() {
        return baseMapper.selectLatestTwoBank();
    }

    @Override
    public WorkOriginalVO getByNewsKey(String newsKey) {
        return this.cover(baseMapper.selectById(newsKey), null);
    }

    @Override
    public IPage<WorkOriginalVO> getPage(Page page, WorkNewsQueryDTO dto) {
        IPage<WorkOriginalEntity> iPage = baseMapper.selectPage(page, Wrappers.<WorkOriginalEntity>lambdaQuery()
                .eq(dto.getState() != null, WorkOriginalEntity::getState, dto.getState())
                .eq(dto.getType() != null, WorkOriginalEntity::getType, dto.getType())
                .eq(dto.getChannel() != null, WorkOriginalEntity::getChannel, dto.getChannel())
                .like(StrUtil.isNotBlank(dto.getTitle()), WorkOriginalEntity::getNewsTitle, dto.getTitle())
                .eq(WorkOriginalEntity::getDelFlag, Integer.parseInt(CommonConstants.STATUS_NORMAL))
                .orderByDesc(WorkOriginalEntity::getNewsTime)
        );
        List<WorkOriginalEntity> recordsSource = iPage.getRecords();
        List<WorkOriginalVO> recordsTarget = new ArrayList<>(recordsSource.size());
        recordsSource.forEach(source -> recordsTarget.add(this.cover(source, dto.getChannel())));
        page.setRecords(recordsTarget);
        return page;
    }

    /**
     * 数据对象转换为展示对象
     * @param source   待转换的数据对象
     * @param channel  待转换数据对象渠道
     * @return         转换后的数据展示对象
     */
    private WorkOriginalVO cover(WorkOriginalEntity source, Integer channel){
        WorkOriginalVO target = new WorkOriginalVO();
        if(ObjectUtil.isNotNull(source)){
            BeanUtil.copyProperties(source, target);
            List<String> tags = JSONUtil.toList(JSONUtil.parseArray(source.getNewsTags()), String.class);
            target.setNewsTags(tags);
            if(ObjectUtil.isNotNull(channel) && NewsChannelEnum.SELF.getChannel() == channel){
                target.setInfoSubType(newsGroupService.getNameByType(
                        source.getType(),
                        Integer.parseInt(NewsTypeEnum.BANK_NEWS.getType())));
            }
            if(ObjectUtil.isNotNull(channel) && NewsChannelEnum.BETA.getChannel() == channel){
                target.setInfoSubType(newsGroupService.getNameByType(
                        source.getType(),
                        Integer.parseInt(NewsTypeEnum.ORIGINAL.getType())));
            }
        }
        return target;
    }
}
